/*
 * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 * 
**/
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDBusArgument>
#include <QFile>
#include <QProcessEnvironment>
#include <QScrollBar>
#include <QMessageBox>
#include <QKeyEvent>
#include <QPainter>
#include <QMenu>
#include <QDBusInterface>
#include <QRadioButton>
#include <QSettings>
#include <QGSettings>
#include <unistd.h>
#include <pwd.h>
#include <QToolTip>
#include <KWindowSystem>
#include <QPainterPath>
#include <QPainter>
#include "contentpane.h"
#include "customtype.h"
#include "messagedialog.h"
#include "aboutdialog.h"
#include "configuration.h"
#include "attributewindow.h"
#include "kalabel.h"
#include "loadingdialog.h"
//#include "highlight-effect.h"

#define ICON_SIZE 32
#define ICON_TYPE_SCHENA "org.ukui.style"
#define FONT_SIZE "system-font-size"
MainWindow::MainWindow(QString usernameFromCmd, QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::MainWindow),
    username(usernameFromCmd),
    verificationStatus(false),
    loginSwitch(false),
    saverSwitch(false),
    systemSwitch(false),
    dragWindow(false),
    mWatcher(nullptr),
    lastDeviceInfo(nullptr),
    aboutDlg(nullptr)
{
    setAttribute(Qt::WA_TranslucentBackground);
    connect(WindowManager::self(),&WindowManager::windowAdded,this,[=](const WindowId& windowId){
        /*注意：
         * 最新创建的窗体被设置为操作窗体，此demo中每个按钮对应一个接口函数调用，所有接口函数操作的窗口都是该最新创建的窗体
         */
        if (getpid() == WindowManager::getPid(windowId)) {
            m_listWinIds.append(windowId);
        }
    });
    connect(WindowManager::self(),&WindowManager::windowRemoved,this,[=](const WindowId& windowId){
        if (m_listWinIds.contains(windowId)) {
            m_listWinIds.removeOne(windowId);
        }
    });
	ui->setupUi(this);
    permissionLabel = new QLabel(ui->PermissionsWidget);
    permissionLabel->installEventFilter(this);
    prettify();

    initialize();
    QFileSystemWatcher *mWatcher = new QFileSystemWatcher(this);
    mWatcher->addPath(Configuration::configFile);
    connect(mWatcher,&QFileSystemWatcher::fileChanged,this,[=](const QString &path){
        mWatcher->addPath(Configuration::configFile);
        QString deviceName = Configuration::instance()->getDefaultDevice();
        Configuration::instance()->defaultDeviceChanged(deviceName);
    });

    if(QGSettings::isSchemaInstalled(ICON_TYPE_SCHENA)){
        QGSettings *icon_type = new QGSettings(ICON_TYPE_SCHENA);
        connect(icon_type, &QGSettings::changed,
            this, &MainWindow::onConfigurationChanged);
    }

    m_styleSettings = new QGSettings(ICON_TYPE_SCHENA,"",this);
    m_curFontSize  = m_styleSettings->get("system-font-size").toInt();
    m_curStyle = m_styleSettings->get("styleName").toString();
    connect(m_styleSettings, &QGSettings::changed,
            this, &MainWindow::onConfigurationChanged);
}

MainWindow::~MainWindow()
{
	delete ui;
}

void MainWindow::onConfigurationChanged(QString key)
{
    if(key == "iconThemeName") {
    	ui->lblLogo->setPixmap(QIcon::fromTheme("biometric-manager").pixmap(QSize(24,24)));
        aboutDlg->setIcon();
    }

    if(key == "systemFontSize"){
        if(m_styleSettings->get("system-font-size").toInt() > 0){
            m_curFontSize  = m_styleSettings->get("system-font-size").toInt();
            initPermissionWidget();
        }
    }
    if(key == "styleName"){
        m_curStyle = m_styleSettings->get("styleName").toString();
        initPermissionWidget();
    }
}

void MainWindow::initPermissionWidget()
{
    QFont permissionsFont = ui->labelPermissions_2->font();
    if(m_curFontSize >= 0)
        permissionsFont.setPointSize(m_curFontSize);
    ui->labelPermissions_2->setFont(permissionsFont);
    if(m_curStyle == "ukui-dark" || m_curStyle == "ukui-black"){
        permissionLabel->setStyleSheet("background-color: black; border-radius: 8px;border: 1px solid grey;");
        systemLabel->setStyleSheet("background-color: black;border-bottom-left-radius: 8px;border-bottom-right-radius: 8px;border: 1px solid grey;");
        saverLabel->setStyleSheet("background-color: black;border-style:solid;border-left-width: 1px; border-color:grey;border-right-width: 1px;");
        greetLabel->setStyleSheet("background-color: black;border-top-left-radius: 8px;border-top-right-radius: 8px;border: 1px solid grey;");
    } else {
        permissionLabel->setStyleSheet("background-color: white; border-radius: 8px;border: 1px solid #E7E7E7;");
        systemLabel->setStyleSheet("background-color: white;border-bottom-left-radius: 8px;border-bottom-right-radius: 8px;border: 1px solid #E7E7E7;");
        saverLabel->setStyleSheet("background-color: white;border-style:solid;border-left-width: 1px; border-color:#E7E7E7;border-right-width: 1px;");
        greetLabel->setStyleSheet("background-color: white;border-top-left-radius: 8px;border-top-right-radius: 8px;border: 1px solid #E7E7E7;");
    }
    QTimer::singleShot(50, this, [&,this](){
        permissionLabel->setFixedHeight(ui->PermissionsWidget->height());
    });
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    //qDebug()<<"ui->PermissionsWidget3"<<ui->PermissionsWidget->height();
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    if(obj->objectName() == "labelIcon"){
        if(event->type() == QEvent::ToolTip){
            DeviceInfo *deviceInfo;
            for(auto info : deviceInfosMap[ui->listWidgetDevicesType->currentIndex()]) {
                if(info->device_shortname == obj->property("devicename").toString()) {
                    if(dialog)
                        return false;
                    deviceInfo = info;
                    dialog =new AttributeWindow(deviceInfo, this);
                    int x = QCursor::pos().x();
                    int y = QCursor::pos().y();
                    dialog->setGeometry(x+ 10, y+ 10, dialog->width(), dialog->height());
                    dialog->show();
                    break;
                }

            }
        }
        else if(event->type() == QEvent::Leave){
            if(dialog == nullptr)
                return false;
            dialog->hide();
            dialog->close();
            dialog = nullptr;
        }
    }

//    if(obj == ui->PermissionsWidget){qDebug()<<"jinlaile";
//        if(event->type() == QEvent::Resize){qDebug()<<"jinlaile";

//    }
//    }
    return false;
}



void MainWindow::mousePressEvent(QMouseEvent *event)
{
 /*
    if(event->button() == Qt::LeftButton) {
        dragPos = event->globalPos() - pos();
        dragWindow = true;
    }
 */
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
 /*
    if(dragWindow) {
        move(event->globalPos() - dragPos);
    }
 */   
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_F1) {
        if(!daemonIsNotRunning()){
            showGuide("biometric-manager");
        }
    }
}

int MainWindow::daemonIsNotRunning()
{
    QString service_name = "com.kylinUserGuide.hotel_" + QString::number(getuid());
    QDBusConnection conn = QDBusConnection::sessionBus();
    if (!conn.isConnected())
        return 0;

    QDBusReply<QString> reply = conn.interface()->call("GetNameOwner", service_name);
    return reply.value() == "";
}


void MainWindow::showGuide(QString appName)
{
    qDebug() << Q_FUNC_INFO << appName;

    QString service_name = "com.kylinUserGuide.hotel_" + QString::number(getuid());

    QDBusInterface *interface = new QDBusInterface(service_name,
                                                       KYLIN_USER_GUIDE_PATH,
                                                       KYLIN_USER_GUIDE_INTERFACE,
                                                       QDBusConnection::sessionBus(),
                                                       this);

    QDBusMessage msg = interface->call(QStringLiteral("showGuide"),"biometric-manager");
}

void MainWindow::mouseReleaseEvent(QMouseEvent */*event*/)
{
    dragWindow = false;
}

void MainWindow::prettify()
{
    setWindowFlags(Qt::WindowCloseButtonHint);
	/* 设置窗口图标 */
    QApplication::setWindowIcon(QIcon::fromTheme("biometric-manager"));
    /* 设置 CSS */
//    QFile qssFile(":/css/assets/mainwindow.qss");
//    qssFile.open(QFile::ReadOnly);
//    QString styleSheet = QLatin1String(qssFile.readAll());
//    this->setStyleSheet(qssFile.readAll());
//    qssFile.close();
    ui->stackedWidgetMain->setAutoFillBackground(true);
    ui->stackedWidgetMain->setBackgroundRole(QPalette::Base);
    ui->widgetHeader_2->setAutoFillBackground(true);
    ui->widgetHeader_2->setBackgroundRole(QPalette::Base);

    QPalette pe;
    pe.setColor(QPalette::WindowText,Qt::gray);
    ui->labelPermission->setPalette(pe);
    ui->labelVarieties->setPalette(pe);
    ui->labelPermission->setContentsMargins(16,6,16,6);
    ui->labelVarieties->setContentsMargins(16,6,16,6);
    ui->labelVarieties->setText(tr("Password Setting"));
    ui->lblTitle->setText(tr("Biometric Manager"));
    ui->labelBiometric->setText(tr("Biometric"));
    ui->labelBiometric->adjustSize();
    ui->labelDeviceType->setText(tr("Select Device Type"));
    ui->labelDeviceType->adjustSize();
    QPixmap noDeviceIcon;
    noDeviceIcon.load(":/images/assets/no-device.svg");
    ui->labelPermissions_2->setWordWrap(true);
    ui->labelPermissions_2->setAlignment(Qt::AlignTop);
    ui->labelPermissions_2->adjustSize();
    ui->labelPermissions_2->setStyleSheet("color:gray");
    ui->PermissionsWidget->adjustSize();

//    ui->lblNoDeviceFingerPrint->setWordWrap(true);
//    ui->lblNoDeviceFingerPrint->setAlignment(Qt::AlignTop);
//    ui->lblNoDeviceFace->setWordWrap(true);
//    ui->lblNoDeviceFace->setAlignment(Qt::AlignTop);
//    ui->lblNoDeviceFingerVein->setWordWrap(true);
//    ui->lblNoDeviceFingerVein->setAlignment(Qt::AlignTop);
//    ui->lblNoDeviceIris->setWordWrap(true);
//    ui->lblNoDeviceIris->setAlignment(Qt::AlignTop);
//    ui->lblNoDeviceVoicePrint->setWordWrap(true);
//    ui->lblNoDeviceVoicePrint->setAlignment(Qt::AlignTop);
    ui->lblNoDeviceIFace->setPixmap(noDeviceIcon);
    ui->lblNoDeviceIFingerPrint->setPixmap(noDeviceIcon);
    ui->lblNoDeviceIFingerVein->setPixmap(noDeviceIcon);
    ui->lblNoDeviceIIris->setPixmap(noDeviceIcon);
    ui->lblNoDeviceIVoicePrint->setPixmap(noDeviceIcon);
//    /* Set Icon for each tab on tabwidget */

    ui->btnPermissions->setIcon(QString(":/images/assets/Permissions.svg"));
    ui->btnDashBoard->setIcon(QString(":/images/assets/Device.svg"));
    ui->btnFingerPrint->setIcon(QString(":/images/assets/FingerPrint.svg"));
    ui->btnFingerVein->setIcon(QString(":/images/assets/FingerVein.svg"));
    ui->btnIris->setIcon(QString(":/images/assets/Iris.svg"));
    ui->btnVoicePrint->setIcon(QString(":/images/assets/VoicePrint.svg"));
    ui->btnFace->setIcon(QString(":/images/assets/faceid.svg"));

//    ui->btnFingerPrint->setStyleSheet("text-align: left;");
//    ui->btnFingerPrint->setProperty("useIconHighlightEffect", 0x8);
//    /* Set logo on lblLogo */
    ui->lblLogo->setPixmap(QIcon::fromTheme("biometric-manager").pixmap(QSize(24,24)));

    ui->btnMin->setProperty("isWindowButton", 0x1);
    ui->btnMin->setProperty("useIconHighlightEffect", 0x2);
    ui->btnMin->setAutoRaise(true);
    ui->btnMin->setFixedSize(30, 30);
    ui->btnMin->setIconSize(QSize(16, 16));
    ui->btnMin->setIcon(QIcon::fromTheme("window-minimize-symbolic"));
    ui->btnMin->setToolTip(tr("Minimize"));

    ui->tableWidgetDevices->setAlternatingRowColors(true);
    ui->tableWidgetDevices->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);

    ui->btnMenu->setProperty("isWindowButton", 0x1);
    ui->btnMenu->setProperty("useIconHighlightEffect", 0x2);
    ui->btnMenu->setAutoRaise(true);
    ui->btnMenu->setFixedSize(30, 30);
    ui->btnMenu->setIconSize(QSize(16, 16));
    ui->btnMenu->setIcon(QIcon::fromTheme("open-menu-symbolic"));
    ui->btnMenu->setToolTip(tr("Main menu"));

    ui->btnClose->setProperty("isWindowButton", 0x2);
    ui->btnClose->setProperty("useIconHighlightEffect", 0x8);
    ui->btnClose->setAutoRaise(true);
    ui->btnClose->setFixedSize(30, 30);
    ui->btnClose->setIconSize(QSize(16, 16));
    ui->btnClose->setIcon(QIcon::fromTheme("window-close-symbolic"));
    ui->btnClose->setToolTip(tr("Close"));

    ui->tableWidgetDevices->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu);

    //permissionLabel->setLayout(ui->horizontalLayout_101);
    permissionLabel->setMinimumWidth(656);
    permissionLabel->lower();
    //permissionLabel->adjustSize();
    systemLabel = new QLabel(ui->systemWindow);
    //greetLabel->setLayout(ui->horizontalLayout_15);
    systemLabel->setMinimumSize(656,ui->systemWindow->height());
    systemLabel->lower();

    saverLabel = new QLabel(ui->saverWindow);
    //greetLabel->setLayout(ui->horizontalLayout_15);
    saverLabel->setMinimumSize(656,ui->saverWindow->height());
    saverLabel->lower();

    greetLabel = new QLabel(ui->greeterWindow);
    //greetLabel->setLayout(ui->horizontalLayout_15);
    greetLabel->setMinimumSize(656,ui->greeterWindow->height());
    greetLabel->lower();
    ui->biometricLabel->hide();
    ui->greeterWindow->hide();
    ui->saverWindow->hide();
    ui->systemWindow->hide();
    initPermissionWidget();
}

QPixmap *MainWindow::getUserAvatar(QString username)
{
    QString iconPath;
    QDBusInterface userIface( "org.freedesktop.Accounts", "/org/freedesktop/Accounts",
              "org.freedesktop.Accounts", QDBusConnection::systemBus());
    if (!userIface.isValid())
        qDebug() << "GUI:" << "userIface is invalid";
    QDBusReply<QDBusObjectPath> userReply = userIface.call("FindUserByName", username);
    if (!userReply.isValid()) {
        qDebug() << "GUI:" << "userReply is invalid";
        iconPath = "/usr/share/kylin-greeter/default_face.png";
    }
    QDBusInterface iconIface( "org.freedesktop.Accounts", userReply.value().path(),
            "org.freedesktop.DBus.Properties", QDBusConnection::systemBus());
    if (!iconIface.isValid())
        qDebug() << "GUI:" << "IconIface is invalid";
    QDBusReply<QDBusVariant> iconReply = iconIface.call("Get", "org.freedesktop.Accounts.User", "IconFile");
    if (!iconReply.isValid()) {
        qDebug() << "GUI:" << "iconReply is invalid";
        iconPath = "/usr/share/kylin-greeter/default_face.png";
    }
    iconPath = iconReply.value().variant().toString();
    if (access(qPrintable(iconPath), R_OK) != 0) /* No Access Permission */
        iconPath = "/usr/share/kylin-greeter/default_face.png";
    return new QPixmap(iconPath);
}

void MainWindow::setCurrentUser()
{
//    struct passwd *pwd;
//    pwd = getpwuid(getuid());
//    username = QString(pwd->pw_name);
//    ui->lblUserName->setText(username);

//    ui->lblAvatar->setPixmap(QPixmap(":/images/assets/avatar.png"));
}

void MainWindow::onReviceWindowMessage(QString message)
{
    QString platform = QGuiApplication::platformName();
    if(platform.startsWith(QLatin1String("wayland"),Qt::CaseInsensitive)) {
        if (!m_listWinIds.isEmpty()) {
            WindowManager::activateWindow(m_listWinIds.back());
        }
    } else {
        KWindowSystem::forceActiveWindow(this->winId());
    }
    this->show();
}

void MainWindow::initialize()
{
    /* 向 QDBus 类型系统注册自定义数据类型 */
    registerCustomTypes();
    /* 连接 DBus Daemon */
    serviceInterface = new QDBusInterface(DBUS_SERVICE, DBUS_PATH,
                                          DBUS_INTERFACE,
                                          QDBusConnection::systemBus());
    serviceInterface->setTimeout(2147483647); /* 微秒 */

    initSysMenu();

    /* 获取并显示用户 */
    setCurrentUser();

    /* 获取设备列表 */
    getDeviceInfo();

    /* Other initializations */
    initDashboardBioAuthSection();
//    initSaverSwitch();
//    initSystemSwitch();
//    initLoginSwitch();
    initBiometricPage();
    initDeviceTypeList();
    connect(ui->btnMin, &QPushButton::clicked, this, &MainWindow::showMinimized);
    connect(ui->btnClose, &QPushButton::clicked, this, &MainWindow::close);

    ui->btnDashBoard->click();

    ui->btnStatus->setCheckable(true);
    connect(ui->btnStatus, &KSwitchButton::clicked, this, &MainWindow::on_btnStatus_clicked);
    connect(ui->btnSaver, &KSwitchButton::clicked, this, &MainWindow::on_btnSaver_clicked);
    connect(ui->btnLogin, &KSwitchButton::clicked, this, &MainWindow::on_btnLogin_clicked);
    connect(ui->btnSystem, &KSwitchButton::clicked, this, &MainWindow::on_btnSystem_clicked);

    connect(serviceInterface, SIGNAL(USBDeviceHotPlug(int, int, int)),
            this, SLOT(onUSBDeviceHotPlug(int,int,int)));
    connect(serviceInterface, SIGNAL(FeatureChanged(int, int, int)),
            this, SLOT(onUpdateDevice(int,int,int)));
}


void MainWindow::initSysMenu()
{
    menu = new QMenu(this);
    QAction *serviceStatusAction = new QAction(tr("Restart Service"), this);
    connect(serviceStatusAction, &QAction::triggered, this, [&]{
        restartService();
    });

    QAction *aboutAction = new QAction(tr("About"), this);
    connect(aboutAction, &QAction::triggered, this, [&]{
        if(aboutDlg == nullptr)
            aboutDlg = new AboutDialog();

        int x = this->geometry().topLeft().x() + (width() - aboutDlg->width()) / 2;
        int y = this->geometry().topLeft().y() + (height() - aboutDlg->height()) / 2;

        aboutDlg->move(x, y);
        aboutDlg->exec();
    });

    QAction *exitAction = new QAction(tr("Exit"), this);
    connect(exitAction, &QAction::triggered, this, [&]{
        close();
    });

    QAction *helpAction = new QAction(tr("Help"), this);
    connect(helpAction, &QAction::triggered, this, [&]{
        if(!daemonIsNotRunning()){
            showGuide("biometric-manager");
        }
    });

    menu->addActions({serviceStatusAction, helpAction,aboutAction,exitAction});
    ui->btnMenu->setPopupMode(QToolButton::InstantPopup   );
    ui->btnMenu->setMenu(menu);
}

void MainWindow::changeBtnColor(QPushButton *btn)
{
    if(btn != ui->btnDashBoard){
        ui->btnDashBoard->setChecked(false);    }
    else{
        ui->btnDashBoard->setChecked(true);
    }
    if(btn != ui->btnFingerPrint){
        ui->btnFingerPrint->setChecked(false);
    }
    else{
        ui->btnFingerPrint->setChecked(true);
    }
    if(btn != ui->btnFingerVein){
        ui->btnFingerVein->setChecked(false);
    }
    else{
        ui->btnFingerVein->setChecked(true);
    }
    if(btn != ui->btnIris){
        ui->btnIris->setChecked(false);
    }
    else{
        ui->btnIris->setChecked(true);
    }
    if(btn != ui->btnVoicePrint){
        ui->btnVoicePrint->setChecked(false);
    }
    else{
        ui->btnVoicePrint->setChecked(true);
    }
    if(btn != ui->btnFace){
        ui->btnFace->setChecked(false);
    }
    else{
        ui->btnFace->setChecked(true);
    }
    if(btn != ui->btnPermissions){
        ui->btnPermissions->setChecked(false);
    }
    else{
        ui->btnPermissions->setChecked(true);
    }
}

void MainWindow::on_btnDashBoard_clicked()
{
    setStackedWidgetMain(ui->pageDashBoard);
    changeBtnColor(ui->btnDashBoard);
}

void MainWindow::on_btnPermissions_clicked()
{
    setStackedWidgetMain(ui->pagePermissions);
    changeBtnColor(ui->btnPermissions);
    initPermissionWidget();
}

void MainWindow::on_btnFingerPrint_clicked()
{
    setStackedWidgetMain(ui->pageFingerPrint);
    changeBtnColor(ui->btnFingerPrint);
}

void MainWindow::on_btnFingerVein_clicked()
{
    setStackedWidgetMain(ui->pageFingerVein);
    changeBtnColor(ui->btnFingerVein);
}

void MainWindow::on_btnIris_clicked()
{
    setStackedWidgetMain(ui->pageIris);
    changeBtnColor(ui->btnIris);
}

void MainWindow::on_btnVoicePrint_clicked()
{
    setStackedWidgetMain(ui->pageVoicePrint);
    changeBtnColor(ui->btnVoicePrint);
}

void MainWindow::on_btnFace_clicked()
{
    setStackedWidgetMain(ui->pageFace);
    changeBtnColor(ui->btnFace);
}

void MainWindow::on_lblNoDevicePFingerPrint_clicked()
{
    setStackedWidgetMain(ui->pageDashBoard);
    changeBtnColor(ui->btnDashBoard);
    ui->listWidgetDevicesType->setCurrentIndex(0);
}

void MainWindow::on_lblNoDevicePFace_clicked()
{
    setStackedWidgetMain(ui->pageDashBoard);
    changeBtnColor(ui->btnDashBoard);
    ui->listWidgetDevicesType->setCurrentIndex(1);
}

void MainWindow::on_lblNoDevicePFingerVein_clicked()
{
    setStackedWidgetMain(ui->pageDashBoard);
    changeBtnColor(ui->btnDashBoard);
    ui->listWidgetDevicesType->setCurrentIndex(2);
}

void MainWindow::on_lblNoDevicePIris_clicked()
{
    setStackedWidgetMain(ui->pageDashBoard);
    changeBtnColor(ui->btnDashBoard);
    ui->listWidgetDevicesType->setCurrentIndex(3);
}

void MainWindow::on_lblNoDevicePVoicePrint_clicked()
{
    setStackedWidgetMain(ui->pageDashBoard);
    changeBtnColor(ui->btnDashBoard);
    ui->listWidgetDevicesType->setCurrentIndex(4);
}

/**
 * @brief 设备类型到索引的映射
 */
int MainWindow::bioTypeToIndex(int type)
{
    switch(type) {
    case BIOTYPE_FINGERPRINT:
        return 0;
    case BIOTYPE_FACE:
        return 1;
    case BIOTYPE_FINGERVEIN:
        return 2;
    case BIOTYPE_IRIS:
        return 3;
    case BIOTYPE_VOICEPRINT:
        return 4;
    }
    return -1;
}

/**
 * @brief 获取设备列表并存储起来备用
 */
void MainWindow::getDeviceInfo()
{
	QVariant variant;
	QDBusArgument argument;
	QList<QDBusVariant> qlist;
	QDBusVariant item;
	DeviceInfo *deviceInfo;

	/* 返回值为 i -- int 和 av -- array of variant */
    QDBusPendingReply<int, QList<QDBusVariant> > reply = serviceInterface->call("GetDrvList");
	reply.waitForFinished();
	if (reply.isError()) {
		qDebug() << "GUI:" << reply.error();
		deviceCount = 0;
		return;
	}

	/* 解析 DBus 返回值，reply 有两个返回值，都是 QVariant 类型 */
	variant = reply.argumentAt(0); /* 得到第一个返回值 */
	deviceCount = variant.value<int>(); /* 解封装得到设备个数 */
	variant = reply.argumentAt(1); /* 得到第二个返回值 */
	argument = variant.value<QDBusArgument>(); /* 解封装，获取QDBusArgument对象 */
	argument >> qlist; /* 使用运算符重载提取 argument 对象里面存储的列表对象 */

    for(int i = 0; i < __MAX_NR_BIOTYPES; i++)
        deviceInfosMap[i].clear();;

	for (int i = 0; i < deviceCount; i++) {
		item = qlist[i]; /* 取出一个元素 */
		variant = item.variant(); /* 转为普通QVariant对象 */
		/* 解封装得到 QDBusArgument 对象 */
		argument = variant.value<QDBusArgument>();
		deviceInfo = new DeviceInfo();
		argument >> *deviceInfo; /* 提取最终的 DeviceInfo 结构体 */

        deviceInfosMap[bioTypeToIndex(deviceInfo->biotype)].append(deviceInfo);

        //qDebug() << deviceInfo->biotype << deviceInfo->device_shortname << deviceInfo->device_available;
	}
}

void MainWindow::setLastDeviceSelected()
{
    if(!lastDeviceInfo)
        return ;

    QComboBox *lw;
    QStackedWidget *sw;

    switch(lastDeviceInfo->biotype) {
    case BIOTYPE_FINGERPRINT:
        lw = ui->listWidgetFingerPrint;
        sw = ui->stackedWidgetFingerPrint;
        break;
    case BIOTYPE_FINGERVEIN:
        lw = ui->listWidgetFingerVein;
        sw = ui->stackedWidgetFingerVein;
        break;
    case BIOTYPE_IRIS:
        lw = ui->listWidgetIris;
        sw = ui->stackedWidgetIris;
        break;
    case BIOTYPE_FACE:
        lw = ui->listWidgetFace;
        sw = ui->stackedWidgetFace;
        break;
    case BIOTYPE_VOICEPRINT:
        lw = ui->listWidgetVoicePrint;
        sw = ui->stackedWidgetVoicePrint;
        break;
    }

    lastDeviceInfo = nullptr;

    for(int i=0;i<lw->count();i++)
    {
        if(lw->currentText()==lastDeviceInfo->device_shortname)
        {
            lw->setCurrentIndex(i);
            sw->setCurrentIndex(i);
        }
    }

    lastDeviceInfo = nullptr;
}

void MainWindow::raiseContentPane(DeviceInfo *deviceInfo)
{
    if(deviceInfo->device_available<=0)
        return ;

    QComboBox *lw;
    QStackedWidget *sw;
    switch(deviceInfo->biotype) {
    case BIOTYPE_FINGERPRINT:
        lw = ui->listWidgetFingerPrint;
        sw = ui->stackedWidgetFingerPrint;
        break;
    case BIOTYPE_FINGERVEIN:
        lw = ui->listWidgetFingerVein;
        sw = ui->stackedWidgetFingerVein;
        break;
    case BIOTYPE_IRIS:
        lw = ui->listWidgetIris;
        sw = ui->stackedWidgetIris;
        break;
    case BIOTYPE_FACE:
        lw = ui->listWidgetFace;
        sw = ui->stackedWidgetFace;
        break;
    case BIOTYPE_VOICEPRINT:
        lw = ui->listWidgetVoicePrint;
        sw = ui->stackedWidgetVoicePrint;
        break;
    }
    for(int i=0;i<lw->count();i++)
    {
        if(lw->itemText(i) == deviceInfo->device_shortname)
        {
            //lw->addItem(deviceInfo->device_shortname);
            QWidget *widget = sw->widget(i);
            sw->removeWidget(sw->widget(i));
            sw->insertWidget(0,widget);
        }
    }

//    for(int i=0;i<lw->count();i++)
//    {
//        if(lw->item(i)->text()==deviceInfo->device_shortname)
//        {
//            QListWidgetItem *item = lw->takeItem(i);
//            lw->insertItem(0,item);
//            QWidget *widget = sw->widget(i);
//            sw->removeWidget(sw->widget(i));
//            sw->insertWidget(0,widget);
//        }
//    }

}

void MainWindow::addContentPane(DeviceInfo *deviceInfo)
{
    QComboBox *lw;
    QStackedWidget *sw;

    switch(deviceInfo->biotype) {
    case BIOTYPE_FINGERPRINT:
        lw = ui->listWidgetFingerPrint;
        sw = ui->stackedWidgetFingerPrint;
        break;
    case BIOTYPE_FINGERVEIN:
        lw = ui->listWidgetFingerVein;
        sw = ui->stackedWidgetFingerVein;
        break;
    case BIOTYPE_IRIS:
        lw = ui->listWidgetIris;
        sw = ui->stackedWidgetIris;
        break;
    case BIOTYPE_FACE:
        lw = ui->listWidgetFace;
        sw = ui->stackedWidgetFace;
        break;
    case BIOTYPE_VOICEPRINT:
        lw = ui->listWidgetVoicePrint;
        sw = ui->stackedWidgetVoicePrint;
        break;
    }

//    QListWidgetItem *item = new QListWidgetItem(deviceInfo->device_shortname);
//    ContentPane *contentPane = new ContentPane(getuid(), deviceInfo);
//    item->setTextAlignment(Qt::AlignCenter);
//    if(deviceInfo->device_available <= 0){
//        lw->insertItem(lw->count(), item);
//        sw->insertWidget(sw->count(),contentPane);
//    }
//    else {
//        lw->insertItem(0,item);
//        sw->insertWidget(0,contentPane);
//    }
//    if(deviceInfo->device_available <= 0)
//        item->setTextColor(Qt::gray);

//    contentPaneMap.insert(deviceInfo->device_shortname, contentPane);

    ContentPane *contentPane = new ContentPane(getuid(), deviceInfo);
    connect(contentPane, &ContentPane::deleteFeatureState, this, &MainWindow::onDeleteFeatureState);
    QString default_Name = Configuration::instance()->getDefaultDevice();
    QString defaultText = tr("(default) ");
    defaultText = defaultText + deviceInfo->device_shortname;
    if(deviceInfo->device_available > 0){
        if(deviceInfo->device_shortname == default_Name)
            lw->addItem(defaultText);
        else
            lw->addItem(deviceInfo->device_shortname);
        sw->insertWidget(sw->count(),contentPane);
    }
//    else {
//        lw->insertItem(0,deviceInfo->device_shortname);
//        sw->insertWidget(0,contentPane);
//    }
//    if(deviceInfo->device_available <= 0)
//        item->setTextColor(Qt::gray);

    contentPaneMap.insert(deviceInfo->device_shortname, contentPane);

    //connect(lw, &QListWidget::currentRowChanged, sw, &QStackedWidget::setCurrentIndex);
    connect(lw, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), sw, &QStackedWidget::setCurrentIndex);
//    connect(contentPane, &ContentPane::changeDeviceStatus, this, &MainWindow::changeDeviceStatus);
}

#define checkBiometricPage(biometric) do {				\
    if (ui->listWidget##biometric->count() >= 1) {			\
        ui->listWidget##biometric->setCurrentIndex(0);		\
		ui->listWidget##biometric->show();			\
        ui->listWidgetA##biometric->show();			\
        ui->listWidgetB##biometric->show();			\
		ui->stackedWidget##biometric->show();			\
        ui->lblNoDeviceW##biometric->hide();			\
	} else {							\
		ui->listWidget##biometric->hide();			\
        ui->listWidgetA##biometric->hide();			\
        ui->listWidgetB##biometric->hide();			\
		ui->stackedWidget##biometric->hide();			\
        ui->lblNoDeviceW##biometric->show();			\
	}								\
} while(0)

void MainWindow::updateBiometricPage(int type ,int devNumNow)
{
    if(type == 0){
        if(devNumNow == 0){
            ui->listWidgetFingerPrint->hide();
            ui->stackedWidgetFingerPrint->hide();
            ui->listWidgetAFingerPrint->hide();
            ui->listWidgetBFingerPrint->hide();
            ui->lblNoDeviceWFingerPrint->show();
        }
        else{
            ui->listWidgetFingerPrint->show();
            ui->stackedWidgetFingerPrint->show();
            ui->listWidgetAFingerPrint->show();
            ui->listWidgetBFingerPrint->show();
            ui->lblNoDeviceWFingerPrint->hide();
        }
    }
    if(type == 1){
        if(devNumNow == 0){
            ui->listWidgetFace->hide();
            ui->stackedWidgetFace->hide();
            ui->listWidgetAFace->hide();
            ui->listWidgetBFace->hide();
            ui->lblNoDeviceWFace->show();
        }
        else{
            ui->listWidgetFace->show();
            ui->stackedWidgetFace->show();
            ui->listWidgetAFace->show();
            ui->listWidgetBFace->show();
            ui->lblNoDeviceWFace->hide();
        }
    }
    if(type == 2){
        if(devNumNow == 0){
            ui->listWidgetFingerVein->hide();
            ui->stackedWidgetFingerVein->hide();
            ui->listWidgetAFingerVein->hide();
            ui->listWidgetBFingerVein->hide();
            ui->lblNoDeviceWFingerVein->show();
            }
        else{
            ui->listWidgetFingerVein->show();
            ui->stackedWidgetFingerVein->show();
            ui->listWidgetAFingerVein->show();
            ui->listWidgetBFingerVein->show();
            ui->lblNoDeviceWFingerVein->hide();
        }
    }
    if(type == 3){
        if(devNumNow == 0){
            ui->listWidgetIris->hide();
            ui->stackedWidgetIris->hide();
            ui->listWidgetAIris->hide();
            ui->listWidgetBIris->hide();
            ui->lblNoDeviceWIris->show();
        }
        else{
            ui->listWidgetIris->show();
            ui->stackedWidgetIris->show();
            ui->listWidgetAIris->show();
            ui->listWidgetBIris->show();
            ui->lblNoDeviceWIris->hide();
        }
    }
    if(type == 4){
        if(devNumNow == 0){
            ui->listWidgetVoicePrint->hide();
            ui->stackedWidgetVoicePrint->hide();
            ui->listWidgetAVoicePrint->hide();
            ui->listWidgetBVoicePrint->hide();
            ui->lblNoDeviceWVoicePrint->show();
        }
        else{
            ui->listWidgetVoicePrint->show();
            ui->stackedWidgetVoicePrint->show();
            ui->listWidgetAVoicePrint->show();
            ui->listWidgetBVoicePrint->show();
            ui->lblNoDeviceWVoicePrint->hide();
        }
    }
}

void MainWindow::initBiometricPage()
{
    ui->listWidgetFingerPrint->clear();
    for(int i = ui->stackedWidgetFingerPrint->count(); i >= 0; i--)
    {
        QWidget* widget = ui->stackedWidgetFingerPrint->widget(i);
        ui->stackedWidgetFingerPrint->removeWidget(widget);
        if (widget) {
            delete widget;
        }
    }
    ui->listWidgetFingerVein->clear();
    for(int i = ui->stackedWidgetFingerVein->count(); i >= 0; i--)
    {
        QWidget* widget = ui->stackedWidgetFingerVein->widget(i);
        ui->stackedWidgetFingerVein->removeWidget(widget);
        if (widget) {
            delete widget;
        }
    }
    ui->listWidgetIris->clear();
    for(int i = ui->stackedWidgetIris->count(); i >= 0; i--)
    {
        QWidget* widget = ui->stackedWidgetIris->widget(i);
        ui->stackedWidgetIris->removeWidget(widget);
        if (widget) {
            delete widget;
        }
    }
    ui->listWidgetVoicePrint->clear();
    for(int i = ui->stackedWidgetVoicePrint->count(); i >= 0; i--)
    {
        QWidget* widget = ui->stackedWidgetVoicePrint->widget(i);
        ui->stackedWidgetVoicePrint->removeWidget(widget);
        if (widget) {
            delete widget;
        }
    }
    ui->listWidgetFace->clear();
    for(int i = ui->stackedWidgetFace->count(); i >= 0; i--)
    {
        QWidget* widget = ui->stackedWidgetFace->widget(i);
        ui->stackedWidgetFace->removeWidget(widget);
        if (widget) {
            delete widget;
        }
    }
    contentPaneMap.clear();

    for(int i = 0; i < __MAX_NR_BIOTYPES; i++){
        for (auto deviceInfo : deviceInfosMap[i]){
            addContentPane(deviceInfo);
        }
    }
    checkBiometricPage(FingerPrint);
    checkBiometricPage(FingerVein);
    checkBiometricPage(Iris);
    checkBiometricPage(VoicePrint);
    checkBiometricPage(Face);
}

void MainWindow::onDeleteFeatureState(int nState)
{
    switch(nState){
    case 0: // 开始删除
        if (!m_isShowDeleteAnimation) {
            m_isShowDeleteAnimation = true;
            m_dialogLoading = new LoadingDialog(this);
            m_dialogLoading->setGeometry(0,0, this->geometry().width(), this->geometry().height());
            m_dialogLoading->show();
        }
        break;
    case 1: // 删除完成
        if (m_isShowDeleteAnimation) {
            m_isShowDeleteAnimation = false;
            if (m_dialogLoading) {
                m_dialogLoading->hide();
                m_dialogLoading->close();
            }
        }
        break;
    }
}

void MainWindow::sortContentPane()
{
    for(int i = 0; i < __MAX_NR_BIOTYPES; i++)
        for (auto deviceInfo : deviceInfosMap[i])
            raiseContentPane(deviceInfo);
    checkBiometricPage(FingerPrint);
    checkBiometricPage(FingerVein);
    checkBiometricPage(Iris);
    checkBiometricPage(VoicePrint);
    checkBiometricPage(Face);
//    if(lastDeviceInfo)
//        setLastDeviceSelected();
}

#define SET_TABLE_ATTRIBUTE(tw) do {					\
	tw->setColumnCount(2);						\
	tw->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);\
	tw->setHorizontalHeaderLabels(QStringList()			\
		<< QString(tr("Device Name")) << QString(tr("Status")));\
	tw->verticalHeader()->setVisible(false);			\
	tw->horizontalHeader()->setSectionResizeMode(1,			\
					QHeaderView::ResizeToContents);	\
	tw->setSelectionMode(QAbstractItemView::NoSelection);		\
} while (0);



void MainWindow::initDashboardBioAuthSection()
{
    QProcess process;
    process.start("bioctl status");
    process.waitForFinished();
    QString output = process.readAllStandardOutput();
    qDebug() << "bioctl status ---" << output;
    if (output.contains("enable", Qt::CaseInsensitive)) {
        setVerificationStatus(true);
    }
    else {
        setVerificationStatus(false);
    }

    QProcess g_process;
    g_process.start("bioctl status greeter");
    g_process.waitForFinished();
    QString g_output = g_process.readAllStandardOutput();
    qDebug() << "bioctl status greeter ---" << g_output;
    if (g_output.contains("enable", Qt::CaseInsensitive)) {
        setLoginSwitch(true);
    }
    else {
        setLoginSwitch(false);
    }

    QProcess s_process;
    s_process.start("bioctl status screensaver");
    s_process.waitForFinished();
    QString s_output = s_process.readAllStandardOutput();
    qDebug() << "bioctl status screensaver ---" << s_output;
    if (s_output.contains("enable", Qt::CaseInsensitive)) {
        setSaverSwitch(true);
    }
    else {
        setSaverSwitch(false);
    }

    QProcess p_process;
    p_process.start("bioctl status polkit");
    p_process.waitForFinished();
    QString p_output = p_process.readAllStandardOutput();
    qDebug() << "bioctl status polkit ---" << p_output;
    if (p_output.contains("enable", Qt::CaseInsensitive)) {
        setSystemSwitch(true);
    }
    else {
        setSystemSwitch(false);
    }

    if(!mWatcher){
        mWatcher = new QFileSystemWatcher(this);
        mWatcher->addPath("/etc/biometric-auth/ukui-biometric.conf");
        connect(mWatcher,&QFileSystemWatcher::fileChanged,this,[=](const QString &path){
            mWatcher->addPath("/etc/biometric-auth/ukui-biometric.conf");
            initDashboardBioAuthSection();
        });
    }
}

void MainWindow::initLoginSwitch()
{
    if(loginSwitch)
        setLoginSwitch(true);
    else
        setLoginSwitch(false);
}

void MainWindow::initSaverSwitch()
{
    if(saverSwitch)
        setSaverSwitch(true);
    else
        setSaverSwitch(false);
}

void MainWindow::initSystemSwitch()
{
    if(systemSwitch)
        setSystemSwitch(true);
    else
        setSystemSwitch(false);
}

void MainWindow::initDeviceTypeList()
{
    QStringList devicesTypeText = {tr("FingerPrint"),  tr("Face"), tr("FingerVein"),
                                   tr("Iris"), tr("VoicePrint")};
    for(int i = 0; i < devicesTypeText.size(); i++)
        ui->listWidgetDevicesType->insertItem(ui->listWidgetDevicesType->count(), devicesTypeText[i]);

    ui->listWidgetDevicesType->setCurrentIndex(0);
}


void MainWindow::setVerificationStatus(bool status)
{
   QString statusStyle;

   verificationStatus = status;

   if (status) {
        ui->biometricLabel->show();
        ui->greeterWindow->show();
        ui->saverWindow->show();
        ui->systemWindow->show();
        ui->btnStatus->setChecked(true);
   }
   else {
       ui->biometricLabel->hide();
       ui->greeterWindow->hide();
       ui->saverWindow->hide();
       ui->systemWindow->hide();
       ui->btnStatus->setChecked(false);
   }
}

void MainWindow::on_btnStatus_clicked()
{
    QProcess process;
    QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
    if (verificationStatus) {
        process.start("bioctl disable");
        process.waitForFinished(-1);
//        if (process.exitCode() == 0)
//            setVerificationStatus(false);
    } else {
        process.start("bioctl enable");
        process.waitForFinished(-1);
//        if (process.exitCode() == 0)
//            setVerificationStatus(true);
    }
}

void MainWindow::on_btnLogin_clicked()
{
    ui->btnLogin->setChecked(false);
    QProcess process;
    QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
    if (loginSwitch) {
        process.start("bioctl disable greeter");
        process.waitForFinished(-1);
//        if (process.exitCode() == 0)
//            setLoginSwitch(false);
    } else {
        process.start("bioctl enable greeter");
        process.waitForFinished(-1);
//        if (process.exitCode() == 0)
//            setLoginSwitch(true);
    }
}

void MainWindow::on_btnSaver_clicked()
{
    QProcess process;
    if (saverSwitch) {
        process.start("bioctl disable screensaver");
        process.waitForFinished(-1);
//        if (process.exitCode() == 0)
//            setSaverSwitch(false);
    } else {
        process.start("bioctl enable screensaver");
        process.waitForFinished(-1);
//        if (process.exitCode() == 0)
//            setSaverSwitch(true);
    }
}

void MainWindow::on_btnSystem_clicked()
{
    QProcess process;
    if (systemSwitch) {
        process.start("bioctl disable polkit");
        process.waitForFinished(-1);
//        if (process.exitCode() == 0)
//            setSystemSwitch(false);
    } else {
        process.start("bioctl enable polkit");
        process.waitForFinished(-1);
//        if (process.exitCode() == 0)
//            setSystemSwitch(true);
    }
}

void MainWindow::setSaverSwitch(bool status)
{
   saverSwitch = status;
   if (status) {
       ui->btnSaver->setChecked(true);
       //Configuration::instance()->setSaverSwitch(status);
   }
   else {
       ui->btnSaver->setChecked(false);
       //Configuration::instance()->setSaverSwitch(status);
   }
}

void MainWindow::setLoginSwitch(bool status)
{
   loginSwitch = status;
   if (status) {
       ui->btnLogin->setChecked(true);
       //Configuration::instance()->setSaverSwitch(status);
   }
   else {
       ui->btnLogin->setChecked(false);
       //Configuration::instance()->setSaverSwitch(status);
   }
}

void MainWindow::setSystemSwitch(bool status)
{
   systemSwitch = status;
   if (status) {
       ui->btnSystem->setChecked(true);
       //Configuration::instance()->setSystemSwitch(status);
   }
   else {
       ui->btnSystem->setChecked(false);
       //Configuration::instance()->setSystemSwitch(status);
   }
}

void MainWindow::onDefaultDeviceChanged(bool checked)
{
    QString objName = sender()->objectName();
    QString deviceName = objName;

    for(auto cb : btnGroup)
        if(cb != sender())
            cb->setChecked(false);

    if(checked)
        Configuration::instance()->setDefaultDevice(deviceName);
    else
        Configuration::instance()->setDefaultDevice("");
    on_listWidgetDevicesType_currentIndexChanged(ui->listWidgetDevicesType->currentIndex());
    initBiometricPage();
}

void MainWindow::on_listWidgetDevicesType_currentIndexChanged(int currentRow)
{
    int deviceType = (currentRow);
    QStringList headerData;
    headerData << "    " + tr("Name") << tr("Status") << tr("Default") << tr("Driver");
    m_listSwitchBtns.clear();
    ui->tableWidgetDevices->hide();
    ui->tableWidgetDevices->clear();
    ui->tableWidgetDevices->setRowCount(0);
    ui->tableWidgetDevices->setColumnCount(4);
    ui->tableWidgetDevices->setHorizontalHeaderLabels(headerData);
    //ui->tableWidgetDevices->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为，以行为单位
    ui->tableWidgetDevices->setSelectionMode(QAbstractItemView::NoSelection);

    ui->tableWidgetDevices->setFocusPolicy(Qt::NoFocus);

    for(int i = 0; i < headerData.size(); i++){
        if(i  == 0)
            ui->tableWidgetDevices->horizontalHeaderItem(i)->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
        else
            ui->tableWidgetDevices->horizontalHeaderItem(i)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    }
    ui->tableWidgetDevices->setColumnWidth(0, 250);
    ui->tableWidgetDevices->setColumnWidth(1, 152);
    ui->tableWidgetDevices->setColumnWidth(2, 95);
    ui->tableWidgetDevices->setColumnWidth(3, 143);

    int column = 0;
    
    while(!btnGroup.isEmpty())
    {
           QRadioButton *box = btnGroup.last();
           btnGroup.removeLast();
           delete  box;
    }
    
    for(int i=0;i<deviceInfosMap[deviceType].count();i++)
    {
        if(deviceInfosMap[deviceType].at(i)->device_available > 0)
        {
            deviceInfosMap[deviceType].move(i,0);
        }
    }
    for(auto deviceInfo : deviceInfosMap[deviceType]) {
        if(bioTypeToIndex(deviceInfo->biotype) == deviceType) {
            int row_index = ui->tableWidgetDevices->rowCount();
            if(column == 0)
                ui->tableWidgetDevices->insertRow(row_index);
            else
                row_index--;

            //第一 设备名称
            QWidget *item_name = new QWidget(ui->tableWidgetDevices);

//            item_name->setFlags(item_name->flags() ^ Qt::ItemIsEditable);
//            ui->tableWidgetDevices->setItem(row_index, column, item_name);
            QPushButton *labelIcon = new QPushButton(this);

            labelIcon->setObjectName("labelIcon");
            labelIcon->installEventFilter(this);
//            labelIcon->setCursor(QCursor(Qt::PointingHandCursor));
//            labelIcon->setStyleSheet("QPushButton{border:none;}");
            labelIcon->setFlat(true);
//            labelIcon->setStyleSheet("border-radius:8px");
            labelIcon->setEnabled(false);
            labelIcon->setMaximumSize(20,20);
            KALabel *labelName = new KALabel(this);
            labelName->setMaximumWidth(150);
            QHBoxLayout *layout_name = new QHBoxLayout;
            layout_name->addWidget(labelIcon);
            labelIcon->setIcon(QIcon::fromTheme("preferences-system-details-symbolic"));
            layout_name->setProperty("useIconHighlightEffect", 0x8);
            //labelIcon->adjustSize();

            layout_name->addWidget(labelName);
            labelName->setText(deviceInfo->device_shortname);
            labelName->adjustSize();
            layout_name->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
            item_name->setLayout(layout_name);
            labelIcon->setProperty("devicename",deviceInfo->device_shortname);
            ui->tableWidgetDevices->setCellWidget(row_index, column, item_name);

            //第三 默认设备（是否设为默认设备）
            QWidget *item_default = new QWidget(ui->tableWidgetDevices);
            item_default->setObjectName("itemDefalut");
            QRadioButton *cbDefault = new QRadioButton(this);

            if(Configuration::instance()->getDefaultDevice() == deviceInfo->device_shortname)
                cbDefault->setChecked(true);
            btnGroup.push_back(cbDefault);
            cbDefault->setObjectName(deviceInfo->device_shortname);
            connect(cbDefault, &QRadioButton::clicked, this, &MainWindow::onDefaultDeviceChanged);
            connect(Configuration::instance(), &Configuration::defaultDeviceChanged,
                    this, [&](const QString &deviceName) {
                for(auto btn : btnGroup)
                    btn->setChecked(false);

                QString objName = deviceName;
                QRadioButton *check = findChild<QRadioButton*>(objName);
                if(check) {
                    check->setChecked(true);
                }
            });
            if(cbDefault->isChecked())
            {
                labelName->setText(tr("(default) ") + deviceInfo->device_shortname);
            } else
                labelName->setText(deviceInfo->device_shortname);

            QHBoxLayout *layout_default = new QHBoxLayout;
            layout_default->addWidget(cbDefault);
            layout_default->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
            item_default->setLayout(layout_default);
            ui->tableWidgetDevices->setCellWidget(row_index, column + 2, item_default);

            int flag = 0;

            //第四 驱动状态（是否使能）
            QWidget *item_drvStatus = new QWidget();
            KSwitchButton *btnDrvStatus = new KSwitchButton(this);
            //QPushButton *btnDrvStatus = new QPushButton(this);
            btnDrvStatus->setObjectName(deviceInfo->device_shortname + "_" + QString::number(deviceType));
            btnDrvStatus->setFixedSize(40, 20);
            if(deviceInfo->driver_enable > 0){
                btnDrvStatus->setChecked(true);
            }else{
                flag = 1 ;
                btnDrvStatus->setChecked(false);
            }
            connect(btnDrvStatus, &KSwitchButton::clicked, this, &MainWindow::onDriverStatusClicked);
            m_listSwitchBtns.append(btnDrvStatus);

            QVBoxLayout *layout = new QVBoxLayout(item_drvStatus);
            layout->addWidget(btnDrvStatus, 0, Qt::AlignVCenter | Qt::AlignHCenter);
            layout->setMargin(0);
            item_drvStatus->setLayout(layout);
            ui->tableWidgetDevices->setCellWidget(row_index, column + 3, item_drvStatus);

            //第二 设备状态（是否连接）
            QWidget *item_devStatus = new QWidget(ui->tableWidgetDevices);
            QHBoxLayout *layout_Status = new QHBoxLayout;
            QLabel *label = new QLabel(this);
            layout_Status->addWidget(label);
            QLabel *label1 = new QLabel(this);
            layout_Status->addWidget(label1);
            setDeviceStatus(item_devStatus, label, label1, deviceInfo->device_available > 0, flag);
            layout_Status->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
            //layout_Status->setContentsMargins(20,0,0,0);
            item_devStatus->setLayout(layout_Status);
            ui->tableWidgetDevices->setCellWidget(row_index, column + 1, item_devStatus);
            ui->tableWidgetDevices->setRowHeight(row_index, 45);
//            column = (column + 4) % 4;
        }
    }
    ui->tableWidgetDevices->show();
}

void MainWindow::onDriverStatusClicked()
{
    QString objNameStr = sender()->objectName();
    KSwitchButton* switchBtn = qobject_cast<KSwitchButton*>(sender());
    qDebug() << objNameStr;
    int spliter = objNameStr.lastIndexOf('_');
    QString deviceName = objNameStr.left(spliter);
    int deviceType = objNameStr.right(objNameStr.length() - spliter - 1).toInt();

    qDebug() << deviceName << deviceType;

    if(deviceType != ui->listWidgetDevicesType->currentIndex())
        return;
    DeviceInfo *deviceInfo;
    for(auto info : deviceInfosMap[deviceType]) {
        if(info->device_shortname == deviceName) {
            deviceInfo = info;
            break;
        }
    }
    changeDeviceStatus(deviceInfo, switchBtn);
}

bool MainWindow::changeDeviceStatus(DeviceInfo *deviceInfo, KSwitchButton* switchBtn)
{
    bool toEnable = deviceInfo->driver_enable <= 0 ? true : false;
    QString cmd;
    m_procEnableDriver = new QProcess(this);
    connect(m_procEnableDriver, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
            this, [&,this,toEnable,switchBtn](int exitCode, QProcess::ExitStatus status){
        qDebug()<<"Exit code:"<<exitCode;
        if (this->m_dialogLoading) {
            this->m_dialogLoading->close();
            update();
        }
        if (exitCode == 0) {
            this->lastDeviceInfo = deviceInfo;
            this->updateDevice();
        } else {
            QMessageBox criitical(QMessageBox::Critical,"",tr("Fail to change device status"));
            criitical.exec();
            if (switchBtn && this->m_listSwitchBtns.contains(switchBtn)) {
                switchBtn->setChecked(!toEnable);
            }
            update();
        }
        m_procEnableDriver->deleteLater();
    });
    m_dialogLoading = new LoadingDialog(this);
    m_dialogLoading->setGeometry(0,0, this->geometry().width(), this->geometry().height());

    if (toEnable) {
        cmd = "pkexec biodrvctl enable " //"pkexec biometric-config-tool enable-driver "
                + deviceInfo->device_shortname;
        qDebug() << cmd;
        m_procEnableDriver->start(cmd);
    } else {
        qDebug() << "disable" << deviceInfo->device_shortname;
        cmd = "pkexec biodrvctl disable " //"pkexec biometric-config-tool disable-driver "
                + deviceInfo->device_shortname;
        qDebug() << cmd;
        m_procEnableDriver->start(cmd);
    }
    m_dialogLoading->show();
    return true;
}

bool MainWindow::restartService()
{
//    QDBusInterface interface("org.freedesktop.systemd1",
//                             "/org/freedesktop/systemd1",
//                             "org.freedesktop.systemd1.Manager",
//                             QDBusConnection::systemBus());
//    QDBusReply<QDBusObjectPath> msg = interface.call("RestartUnit", "biometric-authentication.service", "replace");
//    if(!msg.isValid()) {
//        qDebug() << "restart service: " << msg.error();
//        return false;
//    }
    if (!m_procRestartService) {
        m_procRestartService = new QProcess(this);
        connect(m_procRestartService, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
                this, [&,this](int exitCode, QProcess::ExitStatus status){
            qDebug()<<"Exit code:"<<exitCode;
            if (this->m_dialogLoading) {
                this->m_dialogLoading->close();
                update();
            }
            //if (exitCode == 0) {
            //    this->updateDevice();
            //}
        });
    }
    m_dialogLoading = new LoadingDialog(this);
    QString cmd = QString("pkexec biorestart");
    m_procRestartService->start(cmd);
    m_dialogLoading->setGeometry(0,0, this->geometry().width(), this->geometry().height());
    m_dialogLoading->show();
    return true;
}

void MainWindow::updateDeviceListWidget(int biotype)
{
    QComboBox *lw = nullptr;

    switch(biotype) {
    case BIOTYPE_FINGERPRINT:
        lw = ui->listWidgetFingerPrint;
        break;
    case BIOTYPE_FINGERVEIN:
        lw = ui->listWidgetFingerVein;
        break;
    case BIOTYPE_IRIS:
        lw = ui->listWidgetIris;
        break;
    case BIOTYPE_FACE:
        lw = ui->listWidgetFace;
        break;
    case BIOTYPE_VOICEPRINT:
        lw = ui->listWidgetVoicePrint;
        break;
    }
    if(!lw) return;

    for(int row = 0; row < lw->count(); row++)
    {
        QList<DeviceInfo *> list = deviceInfosMap[bioTypeToIndex(biotype)];
        auto iter = std::find_if(list.begin(), list.end(),
                              [&](DeviceInfo *deviceInfo){
                return deviceInfo->device_shortname == lw->currentText(); });
////        if(iter != std::end(list))
////            item->setTextColor((*iter)->device_available ? Qt::black : Qt::gray);

    }

//    for(int row = 0; row < lw->count(); row++)
//    {
//        QListWidgetItem *item = lw->item(row);
//        QList<DeviceInfo *> list = deviceInfosMap[bioTypeToIndex(biotype)];
//        auto iter = std::find_if(list.begin(), list.end(),
//                              [&](DeviceInfo *deviceInfo){
//                return deviceInfo->device_shortname == item->text(); });
//        if(iter != std::end(list))
//            item->setTextColor((*iter)->device_available ? Qt::black : Qt::gray);

//    }
}

void MainWindow::updateDevice()
{
    setCursor(Qt::WaitCursor);
    //qDebug() << "name:" << deviceInfo->device_shortname;

   //wait for service restart and dbus is ready
    QTimer::singleShot(3000, this, [&,this](){
	    getDeviceInfo();
	    on_listWidgetDevicesType_currentIndexChanged(ui->listWidgetDevicesType->currentIndex());

	   /* for(int i = 0; i < __MAX_NR_BIOTYPES; i++){
		for(auto deviceInfo : deviceInfosMap[i]){
		        ContentPane *contentPane = contentPaneMap[deviceInfo->device_shortname];
		        if(contentPane){
		    		contentPane->setDeviceInfo(deviceInfo);
		    		contentPane->showFeatures();
		        }else{
		            addContentPane(deviceInfo);
		        }
		}
		updateDeviceListWidget(i);
	    }*/
	    initBiometricPage();
	    setCursor(Qt::ArrowCursor);
	    sortContentPane();
    });
}

void MainWindow::on_tableWidgetDevices_cellDoubleClicked(int row, int column)
{
    if(column % 4 != 0)
        return;
    int index = row ;

    if(index < deviceInfosMap[ui->listWidgetDevicesType->currentIndex()].size()) {
        int deviceType = ui->listWidgetDevicesType->currentIndex();
        DeviceInfo *deviceInfo =  deviceInfosMap[deviceType][index];
        if(deviceInfo->device_available > 0){
            QComboBox *lw;
            switch(deviceInfo->biotype) {
            case BIOTYPE_FINGERPRINT:
                lw = ui->listWidgetFingerPrint;
                ui->btnFingerPrint->click();
                break;
            case BIOTYPE_FINGERVEIN:
                lw = ui->listWidgetFingerVein;
                ui->btnFingerVein->click();
                break;
            case BIOTYPE_IRIS:
                lw = ui->listWidgetIris;
                ui->btnIris->click();
                break;
            case BIOTYPE_FACE:
                lw = ui->listWidgetFace;
                ui->btnFace->click();
                break;
            case BIOTYPE_VOICEPRINT:
                lw = ui->listWidgetVoicePrint;
                ui->btnVoicePrint->click();
                break;
            }
            lw->setCurrentIndex(index);
        }
    }
}

void MainWindow::onUpdateDevice(int drvid,int uid,int cType)
{
    usleep(500000);  //延迟500ms，否则当控制面板进行重命名时，会出现设备忙导致，指纹列表为空
    for(int type : deviceInfosMap.keys()) {
        auto &deviceInfoList = deviceInfosMap[type];
        for(int i = 0; i < deviceInfoList.size(); i++) {
            auto deviceInfo = deviceInfoList[i];
            if(deviceInfo->device_id == drvid) {
                if (contentPaneMap.contains(deviceInfo->device_shortname)) {
                    ContentPane *pane = contentPaneMap[deviceInfo->device_shortname];
                    if(pane && !pane->getIsShowDialog()){
                        pane->showFeatures();
                    }
                }
            }
        }
    }
}

void MainWindow::onUSBDeviceHotPlug(int drvid, int action, int devNumNow)
{
    qDebug() << "device"<< (action > 0 ? "insert:" : "pull out:");
    qDebug() << "id:" << drvid;
    sleep(1);
    for(int type : deviceInfosMap.keys()) {
        auto &deviceInfoList = deviceInfosMap[type];
        for(int i = 0; i < deviceInfoList.size(); i++) {
            auto deviceInfo = deviceInfoList[i];
            if(deviceInfo->device_id == drvid) {
                qDebug() << "name:" << deviceInfo->device_shortname;
                //更新结构体
                deviceInfo->device_available = devNumNow;
                //更新标签页中的设备状态
                ContentPane *pane = contentPaneMap[deviceInfo->device_shortname];
                if (pane) {
                    pane->clearSubWidgets();
                }
                qDebug()<<"devNumN0w="<<devNumNow;
                updateBiometricPage(type ,devNumNow);
//                if(type != 0)
//                    updateBiometricPage(type);
//                if(type != ui->listWidgetDevicesType->currentIndex())
//                {
//                    return;
//                }
                int row = i / 2;
                int column = i % 2 == 0 ? 1 : 5;
                QWidget *item_devStatus = new QWidget(ui->tableWidgetDevices);
                QHBoxLayout *layout_Status = new QHBoxLayout;
                QLabel *iconLabel = new QLabel(this);
                layout_Status->addWidget(iconLabel);
                QLabel *textLabel = new QLabel(this);
                layout_Status->addWidget(textLabel);
                layout_Status->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
                item_devStatus->setLayout(layout_Status);
                ui->tableWidgetDevices->setCellWidget(row, column, item_devStatus);
                int flag = 0;
                setDeviceStatus(item_devStatus, iconLabel, textLabel, devNumNow > 0, flag);
                if(devNumNow > 0 ){
                    //sortContentPane();
                    on_listWidgetDevicesType_currentIndexChanged(ui->listWidgetDevicesType->currentIndex());
                }
                return;
            }
        }
    }
}

void MainWindow::setDeviceStatus(QWidget *item, QLabel *iconLabel, QLabel *textLabel, bool connected, int flag)
{
    QString deviceStatus;
    if(connected && flag == 0) {
        deviceStatus = tr("Connected");
        iconLabel->setFixedSize(8, 8);
        iconLabel->setStyleSheet("background: #4DF46D; border-radius: 4px; opacity: 1;");
    }
    else if(!connected && flag == 0){
        deviceStatus = tr("Unconnected");
        iconLabel->setFixedSize(8, 8);
        iconLabel->setStyleSheet("background: #939393; border-radius: 4px; opacity: 1;");
    }
    else if(flag == 1){
        deviceStatus = tr("disable");
        iconLabel->setFixedSize(8, 8);
        iconLabel->setStyleSheet("background: #FD1C1C; border-radius: 4px; opacity: 1;");
    }
    textLabel->setText(deviceStatus);
}


void MainWindow::onServiceStatusChanged(bool activate)
{
    if(!activate)
    {
        // 关闭子窗口
        QMap<QString, ContentPane *>::iterator itContentPane = contentPaneMap.begin();
        for (; itContentPane != contentPaneMap.end(); itContentPane++) {
            ContentPane *pane = itContentPane.value();
            if (pane) {
                pane->clearSubWidgets();
            }
        }
        ui->stackedWidgetMain->hide();
        lblPrompt = new QLabel(this);
        lblPrompt->setGeometry(ui->stackedWidgetMain->x(),ui->stackedWidgetMain->y(),
                               ui->stackedWidgetMain->width(),
                               ui->stackedWidgetMain->height());
        lblPrompt->setText(tr("The Service is stopped"));
        lblPrompt->setAlignment(Qt::AlignCenter);
        lblPrompt->setStyleSheet("QLabel{color: red; }");
        lblPrompt->show();
    }
    else
    {
        lblPrompt->hide();
        ui->stackedWidgetMain->show();
        updateDevice();
    }
}

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainterPath path;

    QPainter painter(this);
    painter.setOpacity(1);
    painter.setRenderHint(QPainter::Antialiasing);  // 反锯齿;
    painter.setClipping(true);
    painter.setPen(Qt::transparent);

    path.addRoundedRect(this->rect(), 6, 6);
    path.setFillRule(Qt::WindingFill);
    painter.setBrush(this->palette().base());
    painter.setPen(Qt::transparent);

    painter.drawPath(path);
    QStyleOption opt;
    opt.init(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
}

void MainWindow::setStackedWidgetMain(QWidget* newWidget)
{
    ui->stackedWidgetMain->setCurrentWidget(newWidget);
    //newWidget->adjustSize();
    update();
}
